home *** CD-ROM | disk | FTP | other *** search
- /*
- ** HI-CRYPT.C - Enhanced security S-CODER file encryptor/decryptor
- **
- ** public domain demo by Bob Stout
- */
-
- #include <stdio.h>
- #include <stdlib.h>
- #include <string.h>
-
- /*
- ** Globals & prototypes from CRYPT.C, also in SNIPPETS
- */
-
- extern char *cryptext;
- extern int crypt_length, crypt_ptr;
- void crypt(unsigned char *);
- void bufcrypt(unsigned char *buf, long length);
-
- /*
- ** Other SNIPPETS prototypes from CRC-16.C and CANT.C
- */
-
- unsigned short crc16(char *, unsigned short);
- FILE *cant(char *, char *);
-
- /*
- ** HI-CRYPT.C globals and prototypes
- */
-
- int cryptqual(void); /* Qualify the key */
- void setup(void); /* Set hide_loc, hide_ix, crypt_ptr */
- void shuffle(void); /* Assymetrical block transposition */
- void encrypt(void); /* Encrypt a file */
- void decrypt(void); /* Decrypt a file */
- void usage(void); /* Tell 'm how it works! */
-
- long hide_loc; /* Where we save the file length */
- unsigned hide_ix;
-
- FILE *infile, *outfile;
-
- union { /* Transposition cipher block */
- char in[16384];
- char proc[256][64];
- char out[64][256];
- } buf;
-
- union { /* Size of the plain text file */
- long len;
- unsigned char blen[4];
- } fsize;
-
- /*
- ** GO - Collect $200...
- */
-
- main(int argc, char *argv[])
- {
- if (5 > argc || NULL == strchr("EeDd", argv[1][0]))
- usage();
- infile = cant(argv[3], "rb");
- outfile = cant(argv[4], "w+b");
- cryptext = argv[2];
- crypt_length = strlen(cryptext);
- if (cryptqual())
- {
- puts("\aHI-CRYPT: Key is not sufficiently complex");
- return EXIT_FAILURE;
- }
- if (strchr("Ee", argv[1][0]))
- encrypt();
- else decrypt();
- fclose(infile);
- fclose(outfile);
- return EXIT_SUCCESS;
- }
-
- /*
- ** They goofed - tell 'em how it works!
- */
-
- void usage(void)
- {
- puts("\aUsage: HI-CRYPT { E | D } key input_file output_file");
- puts("where: E = Encrypt");
- puts(" D = Decrypt");
- puts("NOTE : If the key contains spaces, it must be enclosed "
- "in quotation marks");
- exit(EXIT_FAILURE);
- }
-
- /*
- ** The key must be 64 bits or more and contain at least 5 distinct chars
- */
-
- int cryptqual(void)
- {
- int i, j = 0;
- static char found[6];
-
- memset(found, 0, 6);
- if (8 > crypt_length)
- return -1;
- for (i = 0; i < crypt_length; ++i)
- {
- if (strchr(found, cryptext[i]))
- continue;
- found[j++] = cryptext[i];
- if (5 < j)
- return 0;
- }
- return -1;
- }
-
- /*
- ** Scramble transposition block buffer
- */
-
- void shuffle(void)
- {
- int i;
- static char buf2[16384];
- char *p = buf2;
-
- for (i = 0; i < 64; ++i)
- {
- memcpy(p, buf.out[63 - i], 256);
- p = &p[256];
- }
- memcpy(buf.in, buf2, 16384);
- }
-
- /*
- ** Compute the location to save the file size
- */
-
- void setup(void)
- {
- unsigned short crc;
-
- crc = crc16(cryptext, crypt_length);
- hide_ix = crc % (16384 - sizeof(long));
- hide_loc = (long)(sizeof(long) + hide_ix);
- crypt_ptr = crc % crypt_length;
- srand(hide_ix);
- }
-
- /*
- ** Encrypt a file
- */
-
- void encrypt(void)
- {
- unsigned i, j, n;
- long swap1, swap2;
-
- /*
- ** Get the file size
- */
-
- setup();
- fseek(infile, 0L, SEEK_END);
- fsize.len = ftell(infile);
- rewind(infile);
-
- /*
- ** Encrypt & save the file size
- */
-
- for (i = 0; i < sizeof(long); ++i)
- crypt(&fsize.blen[i]);
- fwrite(&fsize.len, sizeof(long), 1, outfile);
-
- /*
- ** Encrypt the plaintext
- */
-
- while (0 != (n = fread(buf.in, 1, 16384, infile)))
- {
- while (16384 > n)
- buf.in[n++] = rand();
- for (i = 0; i < 64; ++i)
- {
- for (j = 0; j < 256; ++j)
- crypt(&buf.proc[j][63 - i]);
- }
- shuffle();
- fwrite(buf.in, 1, 16384, outfile);
- }
-
- /*
- ** Relocate the file size
- */
-
- fseek(outfile, hide_loc, SEEK_SET);
- fread(&swap2, sizeof(long), 1, outfile);
- rewind(outfile);
- fread(&swap1, sizeof(long), 1, outfile);
- fseek(outfile, hide_loc, SEEK_SET);
- fwrite(&swap1, sizeof(long), 1, outfile);
- rewind(outfile);
- fwrite(&swap2, sizeof(long), 1, outfile);
- }
-
- /*
- ** Decrypt a file
- */
-
- void decrypt(void)
- {
- unsigned i, j, n;
- int block_1 = -1;
- long hide_buf;
-
- /*
- ** Retrieve & decrypt the file size
- */
-
- setup();
- fseek(infile, hide_loc, SEEK_SET);
- fread(&fsize.len, sizeof(long), 1, infile);
- rewind(infile);
- fread(&hide_buf, sizeof(long), 1, infile);
- for (i = 0; i < sizeof(long); ++i)
- crypt(&fsize.blen[i]);
-
- /*
- ** Decrypt the ciphertext
- */
-
- while (0 != (n = fread(buf.in, 1, 16384, infile)))
- {
- if (block_1)
- {
- block_1 = 0;
- memcpy(&buf.in[hide_ix], &hide_buf, sizeof(long));
- }
- shuffle();
- for (i = 0; i < 64; ++i)
- {
- for (j = 0; j < 256; ++j)
- crypt(&buf.proc[j][63 - i]);
- }
- if (16384 <= fsize.len)
- fwrite(buf.in, 1, 16384, outfile);
- else fwrite(buf.in, 1, fsize.len, outfile);
- fsize.len -= n;
- }
- }
-